package news.utils.httpclient;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
  
public class HttpClientManger {  
    private PoolingHttpClientConnectionManager connectionManager;  
    private HttpRequestRetryHandler httpRequestRetryHandler;  
    private static HttpClientManger httpClientManger;  
    private static Lock lock = new ReentrantLock();  
    private volatile AtomicBoolean isShutDown;  
    public void init() {  
        try {  
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new DefaultTrustStrategy()).build();  
            @SuppressWarnings("deprecation")  
            HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;  
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);  
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()  
                    .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build();  
            connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);  
            connectionManager.setMaxTotal(800);  
            connectionManager.setDefaultMaxPerRoute(20);  
            httpRequestRetryHandler = new DefaultRequestRetryHandler();  
            this.isShutDown = new AtomicBoolean(false);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    private HttpClientManger() {  
        super();  
        this.isShutDown = new AtomicBoolean(true);  
        init();  
    }  
  
    public static HttpClientManger newInstance() {  
        lock.lock();  
        if (httpClientManger == null) {  
            httpClientManger = new HttpClientManger();  
        }  
        lock.unlock();  
        return httpClientManger;  
    }  
  
    public CloseableHttpClient getClient() {  
        CloseableHttpClient client = null;  
        lock.lock();  
        if (this.isShutDown.compareAndSet(false, true)) {  
            client = HttpClients.custom().setConnectionManager(this.connectionManager).setRetryHandler(httpRequestRetryHandler).build();  
        }else {  
            init();  
            client = HttpClients.custom().setConnectionManager(connectionManager).setRetryHandler(httpRequestRetryHandler).build();  
        }  
        lock.unlock();  
        return client;  
    }  
      
    public void destory() {  
        if (this.isShutDown.compareAndSet(false, true)) {  
            this.connectionManager.shutdown();  
        }  
        isShutDown = new AtomicBoolean(true);  
    }  
    class DefaultTrustStrategy implements TrustStrategy{  
        @Override  
        public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {  
            return true;  
        }  
  
    }  
}  
